home *** CD-ROM | disk | FTP | other *** search
- Subject: v13i083: Sun RPC, release 3.9, Part06/15
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Stephen X. Nahm <sxn@Sun.COM>
- Posting-number: Volume 13, Issue 83
- Archive-name: rpc3.9/part06
-
- #! /bin/sh
- # This is a shell archive. To extract, remove the header and type "sh filename"
- #
- echo x - etc
- echo creating directory etc
- mkdir etc
- cd etc
- echo x - Makefile
- cat > Makefile <<'Funky_Stuff'
- #
- # @(#)Makefile 1.5 87/11/20 3.9 RPCSRC
- #
- # Files and programs for /etc. rpclib must have already been installed.
- #
- DESTDIR=
- CFLAGS= -O
- LIB = -lrpclib
- LDFLAGS= $(LIB)
-
- BIN = portmap rpcinfo
- MISC= rpc
-
- all: ${BIN}
-
- portmap:
- ${CC} ${CFLAGS} -o $@ $@.c ${LDFLAGS}
-
- rpcinfo: getopt.o
- ${CC} ${CFLAGS} -o $@ $@.c getopt.o ${LDFLAGS}
-
- install: ${BIN}
- -mkdir ${DESTDIR}/etc && chown bin ${DESTDIR}/etc && \
- chmod 755 ${DESTDIR}/etc
- @echo "Installing RPC utility files in ${DESTDIR}/etc"
- @set -x;for i in ${BIN}; do \
- (install -s $$i ${DESTDIR}/etc/$$i); done
- @echo "Installing ${DESTDIR}/etc/rpc"
- @set -x;for i in ${MISC}; do \
- (install -c -m 644 $$i ${DESTDIR}/etc/$$i); done
-
- clean:
- rm -f core *.o
- rm -f ${BIN}
-
- depend: ${BIN}
- rm -f makedep
- for i in ${BIN}; do \
- ${CC} -M ${INCPATH} $$i.c | sed 's/\.o//' | \
- awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
- else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
- else rec = rec " " $$2 } } \
- END { print rec } ' >> makedep; done
- echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
- echo '$$r makedep' >>eddep
- echo 'w' >>eddep
- cp Makefile Makefile.bak
- ed - Makefile < eddep
- rm eddep makedep
- echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
- echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
- echo '# see make depend above' >> Makefile
-
-
- depend.42BSD depend.42bsd:
- cp /dev/null x.c
- for i in $(BIN) ; do \
- (/bin/grep '^#[ ]*include' x.c $$i.c | sed \
- -e 's,<\(.*\)>,"/usr/include/\1",' \
- -e 's/:[^"]*"\([^"]*\)".*/: \1/' \
- -e 's/\.c/\.o/' >>makedep); done
- echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
- echo '$$r makedep' >>eddep
- echo 'w' >>eddep
- cp Makefile Makefile.bak
- ed - Makefile < eddep
- rm eddep makedep x.c
- echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
- echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
- echo '# see make depend above' >> Makefile
-
- # DO NOT DELETE THIS LINE -- make depend uses it
-
-
- Funky_Stuff
- len=`wc -c < Makefile`
- if [ $len != 2046 ] ; then
- echo error: Makefile was $len bytes long, should have been 2046
- fi
- echo x - getopt.c
- cat > getopt.c <<'Funky_Stuff'
- /* @(#)getopt.c 1.2 87/11/30 3.9 RPCSRC */
-
- /* this is a public domain version of getopt */
-
- /*LINTLIBRARY*/
- #ifndef NULL
- #define NULL 0
- #endif NULL
- #ifndef EOF
- #define EOF (-1)
- #endif EOF
-
- #define ERR(s, c) if(opterr){\
- extern int strlen(), write();\
- char errbuf[2];\
- errbuf[0] = c; errbuf[1] = '\n';\
- (void) write(2, argv[0], strlen(argv[0]));\
- (void) write(2, s, strlen(s));\
- (void) write(2, errbuf, 2);}
-
- #define strchr index
-
- extern int strcmp();
- extern char *strchr();
-
- int opterr = 1;
- int optind = 1;
- int optopt;
- char *optarg;
-
- int
- getopt(argc, argv, opts)
- int argc;
- char **argv, *opts;
- {
- static int sp = 1;
- register int c;
- register char *cp;
-
- if(sp == 1)
- if(optind >= argc ||
- argv[optind][0] != '-' || argv[optind][1] == '\0')
- return(EOF);
- else if(strcmp(argv[optind], "--") == NULL) {
- optind++;
- return(EOF);
- }
- optopt = c = argv[optind][sp];
- if(c == ':' || (cp=strchr(opts, c)) == NULL) {
- ERR(": unknown option, -", c);
- if(argv[optind][++sp] == '\0') {
- optind++;
- sp = 1;
- }
- return('?');
- }
- if(*++cp == ':') {
- if(argv[optind][sp+1] != '\0')
- optarg = &argv[optind++][sp+1];
- else if(++optind >= argc) {
- ERR(": argument missing for -", c);
- sp = 1;
- return('?');
- } else
- optarg = argv[optind++];
- sp = 1;
- } else {
- if(argv[optind][++sp] == '\0') {
- sp = 1;
- optind++;
- }
- optarg = NULL;
- }
- return(c);
- }
- Funky_Stuff
- len=`wc -c < getopt.c`
- if [ $len != 1381 ] ; then
- echo error: getopt.c was $len bytes long, should have been 1381
- fi
- echo x - portmap.c
- cat > portmap.c <<'Funky_Stuff'
- /* @(#)portmap.c 1.1 87/11/04 3.9 RPCSRC */
- #ifndef lint
- static char sccsid[] = "@(#)portmap.c 1.32 87/08/06 Copyr 1984 Sun Micro";
- #endif
-
- /*
- * Copyright (c) 1984 by Sun Microsystems, Inc.
- */
-
- /*
- * portmap.c, Implements the program,version to port number mapping for
- * rpc.
- */
-
- /*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part. Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-
- #include <rpc/rpc.h>
- #include <rpc/pmap_prot.h>
- #include <stdio.h>
- #include <netdb.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <sys/ioctl.h>
- #include <sys/wait.h>
-
- char *malloc();
- int reg_service();
- struct pmaplist *pmaplist;
- static int debugging = 0;
-
- main()
- {
- SVCXPRT *xprt;
- int sock, pid, t;
- struct sockaddr_in addr;
- int len = sizeof(struct sockaddr_in);
- register struct pmaplist *pml;
-
- #ifndef DEBUG
- pid = fork();
- if (pid < 0) {
- perror("portmap: fork");
- exit(1);
- }
- if (pid != 0)
- exit(0);
- for (t = 0; t < 20; t++)
- close(t);
- open("/", 0);
- dup2(0, 1);
- dup2(0, 2);
- t = open("/dev/tty", 2);
- if (t >= 0) {
- ioctl(t, TIOCNOTTY, (char *)0);
- close(t);
- }
- #endif
- if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
- perror("portmap cannot create socket");
- exit(1);
- }
-
- addr.sin_addr.s_addr = 0;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(PMAPPORT);
- if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
- perror("portmap cannot bind");
- exit(1);
- }
-
- if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) {
- fprintf(stderr, "couldn't do udp_create\n");
- exit(1);
- }
- /* make an entry for ourself */
- pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist));
- pml->pml_next = 0;
- pml->pml_map.pm_prog = PMAPPROG;
- pml->pml_map.pm_vers = PMAPVERS;
- pml->pml_map.pm_prot = IPPROTO_UDP;
- pml->pml_map.pm_port = PMAPPORT;
- pmaplist = pml;
-
- if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
- perror("portmap cannot create socket");
- exit(1);
- }
- if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
- perror("portmap cannot bind");
- exit(1);
- }
- if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE))
- == (SVCXPRT *)NULL) {
- fprintf(stderr, "couldn't do tcp_create\n");
- exit(1);
- }
- /* make an entry for ourself */
- pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist));
- pml->pml_map.pm_prog = PMAPPROG;
- pml->pml_map.pm_vers = PMAPVERS;
- pml->pml_map.pm_prot = IPPROTO_TCP;
- pml->pml_map.pm_port = PMAPPORT;
- pml->pml_next = pmaplist;
- pmaplist = pml;
-
- (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE);
- svc_run();
- fprintf(stderr, "run_svc returned unexpectedly\n");
- abort();
- }
-
- static struct pmaplist *
- find_service(prog, vers, prot)
- u_long prog;
- u_long vers;
- {
- register struct pmaplist *hit = NULL;
- register struct pmaplist *pml;
-
- for (pml = pmaplist; pml != NULL; pml = pml->pml_next) {
- if ((pml->pml_map.pm_prog != prog) ||
- (pml->pml_map.pm_prot != prot))
- continue;
- hit = pml;
- if (pml->pml_map.pm_vers == vers)
- break;
- }
- return (hit);
- }
-
- /*
- * 1 OK, 0 not
- */
- reg_service(rqstp, xprt)
- struct svc_req *rqstp;
- SVCXPRT *xprt;
- {
- struct pmap reg;
- struct pmaplist *pml, *prevpml, *fnd;
- int ans, port;
- caddr_t t;
-
- #ifdef DEBUG
- fprintf(stderr, "server: about do a switch\n");
- #endif
- switch (rqstp->rq_proc) {
-
- case PMAPPROC_NULL:
- /*
- * Null proc call
- */
- if ((!svc_sendreply(xprt, xdr_void, NULL)) && debugging) {
- abort();
- }
- break;
-
- case PMAPPROC_SET:
- /*
- * Set a program,version to port mapping
- */
- if (!svc_getargs(xprt, xdr_pmap, ®))
- svcerr_decode(xprt);
- else {
- /*
- * check to see if already used
- * find_service returns a hit even if
- * the versions don't match, so check for it
- */
- fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
- if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) {
- if (fnd->pml_map.pm_port == reg.pm_port) {
- ans = 1;
- goto done;
- }
- else {
- ans = 0;
- goto done;
- }
- } else {
- /*
- * add to END of list
- */
- pml = (struct pmaplist *)
- malloc((u_int)sizeof(struct pmaplist));
- pml->pml_map = reg;
- pml->pml_next = 0;
- if (pmaplist == 0) {
- pmaplist = pml;
- } else {
- for (fnd= pmaplist; fnd->pml_next != 0;
- fnd = fnd->pml_next);
- fnd->pml_next = pml;
- }
- ans = 1;
- }
- done:
- if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
- debugging) {
- fprintf(stderr, "svc_sendreply\n");
- abort();
- }
- }
- break;
-
- case PMAPPROC_UNSET:
- /*
- * Remove a program,version to port mapping.
- */
- if (!svc_getargs(xprt, xdr_pmap, ®))
- svcerr_decode(xprt);
- else {
- ans = 0;
- for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {
- if ((pml->pml_map.pm_prog != reg.pm_prog) ||
- (pml->pml_map.pm_vers != reg.pm_vers)) {
- /* both pml & prevpml move forwards */
- prevpml = pml;
- pml = pml->pml_next;
- continue;
- }
- /* found it; pml moves forward, prevpml stays */
- ans = 1;
- t = (caddr_t)pml;
- pml = pml->pml_next;
- if (prevpml == NULL)
- pmaplist = pml;
- else
- prevpml->pml_next = pml;
- free(t);
- }
- if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
- debugging) {
- fprintf(stderr, "svc_sendreply\n");
- abort();
- }
- }
- break;
-
- case PMAPPROC_GETPORT:
- /*
- * Lookup the mapping for a program,version and return its port
- */
- if (!svc_getargs(xprt, xdr_pmap, ®))
- svcerr_decode(xprt);
- else {
- fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
- if (fnd)
- port = fnd->pml_map.pm_port;
- else
- port = 0;
- if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) &&
- debugging) {
- fprintf(stderr, "svc_sendreply\n");
- abort();
- }
- }
- break;
-
- case PMAPPROC_DUMP:
- /*
- * Return the current set of mapped program,version
- */
- if (!svc_getargs(xprt, xdr_void, NULL))
- svcerr_decode(xprt);
- else {
- if ((!svc_sendreply(xprt, xdr_pmaplist,
- (caddr_t)&pmaplist)) && debugging) {
- fprintf(stderr, "svc_sendreply\n");
- abort();
- }
- }
- break;
-
- case PMAPPROC_CALLIT:
- /*
- * Calls a procedure on the local machine. If the requested
- * procedure is not registered this procedure does not return
- * error information!!
- * This procedure is only supported on rpc/udp and calls via
- * rpc/udp. It passes null authentication parameters.
- */
- callit(rqstp, xprt);
- break;
-
- default:
- svcerr_noproc(xprt);
- break;
- }
- }
-
-
- /*
- * Stuff for the rmtcall service
- */
- #define ARGSIZE 9000
-
- typedef struct encap_parms {
- u_long arglen;
- char *args;
- };
-
- static bool_t
- xdr_encap_parms(xdrs, epp)
- XDR *xdrs;
- struct encap_parms *epp;
- {
-
- return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE));
- }
-
- typedef struct rmtcallargs {
- u_long rmt_prog;
- u_long rmt_vers;
- u_long rmt_port;
- u_long rmt_proc;
- struct encap_parms rmt_args;
- };
-
- static bool_t
- xdr_rmtcall_args(xdrs, cap)
- register XDR *xdrs;
- register struct rmtcallargs *cap;
- {
-
- /* does not get a port number */
- if (xdr_u_long(xdrs, &(cap->rmt_prog)) &&
- xdr_u_long(xdrs, &(cap->rmt_vers)) &&
- xdr_u_long(xdrs, &(cap->rmt_proc))) {
- return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
- }
- return (FALSE);
- }
-
- static bool_t
- xdr_rmtcall_result(xdrs, cap)
- register XDR *xdrs;
- register struct rmtcallargs *cap;
- {
- if (xdr_u_long(xdrs, &(cap->rmt_port)))
- return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
- return (FALSE);
- }
-
- /*
- * only worries about the struct encap_parms part of struct rmtcallargs.
- * The arglen must already be set!!
- */
- static bool_t
- xdr_opaque_parms(xdrs, cap)
- XDR *xdrs;
- struct rmtcallargs *cap;
- {
-
- return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen));
- }
-
- /*
- * This routine finds and sets the length of incoming opaque paraters
- * and then calls xdr_opaque_parms.
- */
- static bool_t
- xdr_len_opaque_parms(xdrs, cap)
- register XDR *xdrs;
- struct rmtcallargs *cap;
- {
- register u_int beginpos, lowpos, highpos, currpos, pos;
-
- beginpos = lowpos = pos = xdr_getpos(xdrs);
- highpos = lowpos + ARGSIZE;
- while ((int)(highpos - lowpos) >= 0) {
- currpos = (lowpos + highpos) / 2;
- if (xdr_setpos(xdrs, currpos)) {
- pos = currpos;
- lowpos = currpos + 1;
- } else {
- highpos = currpos - 1;
- }
- }
- xdr_setpos(xdrs, beginpos);
- cap->rmt_args.arglen = pos - beginpos;
- return (xdr_opaque_parms(xdrs, cap));
- }
-
- /*
- * Call a remote procedure service
- * This procedure is very quiet when things go wrong.
- * The proc is written to support broadcast rpc. In the broadcast case,
- * a machine should shut-up instead of complain, less the requestor be
- * overrun with complaints at the expense of not hearing a valid reply ...
- *
- * This now forks so that the program & process that it calls can call
- * back to the portmapper.
- */
- static
- callit(rqstp, xprt)
- struct svc_req *rqstp;
- SVCXPRT *xprt;
- {
- struct rmtcallargs a;
- struct pmaplist *pml;
- u_short port;
- struct sockaddr_in me;
- int pid, socket = -1;
- CLIENT *client;
- struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;
- struct timeval timeout;
- union wait pinfo;
- char buf[ARGSIZE];
-
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
- a.rmt_args.args = buf;
- if (!svc_getargs(xprt, xdr_rmtcall_args, &a))
- return;
- if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL)
- return;
- /*
- * fork a child to do the work. Parent immediately returns.
- * Child exits upon completion.
- */
- if ((pid = fork()) != 0) {
- if (debugging && (pid < 0)) {
- fprintf(stderr, "portmap CALLIT: cannot fork.\n");
- }
- /* reap previous forks. */
- for (; pid>0; pid = wait3(&pinfo, WNOHANG, (struct rusage *)0));
- return;
- }
- port = pml->pml_map.pm_port;
- get_myaddress(&me);
- me.sin_port = htons(port);
- client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket);
- if (client != (CLIENT *)NULL) {
- if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
- client->cl_auth = authunix_create(au->aup_machname,
- au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids);
- }
- a.rmt_port = (u_long)port;
- if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a,
- xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) {
- svc_sendreply(xprt, xdr_rmtcall_result, &a);
- }
- AUTH_DESTROY(client->cl_auth);
- clnt_destroy(client);
- }
- (void)close(socket);
- exit(0);
- }
- Funky_Stuff
- len=`wc -c < portmap.c`
- if [ $len != 11403 ] ; then
- echo error: portmap.c was $len bytes long, should have been 11403
- fi
- echo x - rpc
- cat > rpc <<'Funky_Stuff'
- #
- # rpc 87/12/02 3.9 RPCSRC
- #
- portmapper 100000 portmap sunrpc
- rstat_svc 100001 rstatd rstat rup perfmeter
- rusersd 100002 rusers
- nfs 100003 nfsprog
- ypserv 100004 ypprog
- mountd 100005 mount showmount
- ypbind 100007
- walld 100008 rwall shutdown
- yppasswdd 100009 yppasswd
- etherstatd 100010 etherstat
- rquotad 100011 rquotaprog quota rquota
- sprayd 100012 spray
- 3270_mapper 100013
- rje_mapper 100014
- selection_svc 100015 selnsvc
- database_svc 100016
- rexd 100017 rex
- alis 100018
- sched 100019
- llockmgr 100020
- nlockmgr 100021
- x25.inr 100022
- statmon 100023
- status 100024
- bootparam 100026
- ypupdated 100028 ypupdate
- keyserv 100029 keyserver
- Funky_Stuff
- len=`wc -c < rpc`
- if [ $len != 787 ] ; then
- echo error: rpc was $len bytes long, should have been 787
- fi
- echo x - rpcinfo.c
- cat > rpcinfo.c <<'Funky_Stuff'
- /* @(#)rpcinfo.c 1.5 87/11/20 3.9 RPCSRC */
- #ifndef lint
- static char sccsid[] = "@(#)rpcinfo.c 1.22 87/08/12 SMI";
- #endif
-
- /*
- * Copyright (C) 1986, Sun Microsystems, Inc.
- */
-
- /*
- * rpcinfo: ping a particular rpc program
- * or dump the portmapper
- */
-
- /*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part. Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-
- #include <rpc/rpc.h>
- #include <stdio.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <netdb.h>
- #include <rpc/pmap_prot.h>
- #include <rpc/pmap_clnt.h>
- #include <signal.h>
- #include <ctype.h>
-
- #define MAXHOSTLEN 256
-
- #define MIN_VERS ((u_long) 0)
- #define MAX_VERS ((u_long) 4294967295L)
-
- static void udpping(/*u_short portflag, int argc, char **argv*/);
- static void tcpping(/*u_short portflag, int argc, char **argv*/);
- static int pstatus(/*CLIENT *client, u_long prognum, u_long vers*/);
- static void pmapdump(/*int argc, char **argv*/);
- static bool_t reply_proc(/*void *res, struct sockaddr_in *who*/);
- static void brdcst(/*int argc, char **argv*/);
- static void usage(/*void*/);
- static u_long getprognum(/*char *arg*/);
- static u_long getvers(/*char *arg*/);
- static void get_inet_address(/*struct sockaddr_in *addr, char *host*/);
- extern u_long inet_addr(); /* in 4.2BSD, arpa/inet.h called that a in_addr */
- extern char *inet_ntoa();
-
- /*
- * Functions to be performed.
- */
- #define NONE 0 /* no function */
- #define PMAPDUMP 1 /* dump portmapper registrations */
- #define TCPPING 2 /* ping TCP service */
- #define UDPPING 3 /* ping UDP service */
- #define BRDCST 4 /* ping broadcast UDP service */
-
- int
- main(argc, argv)
- int argc;
- char **argv;
- {
- register int c;
- extern char *optarg;
- extern int optind;
- int errflg;
- int function;
- u_short portnum;
-
- function = NONE;
- portnum = 0;
- errflg = 0;
- while ((c = getopt(argc, argv, "ptubn:")) != EOF) {
- switch (c) {
-
- case 'p':
- if (function != NONE)
- errflg = 1;
- else
- function = PMAPDUMP;
- break;
-
- case 't':
- if (function != NONE)
- errflg = 1;
- else
- function = TCPPING;
- break;
-
- case 'u':
- if (function != NONE)
- errflg = 1;
- else
- function = UDPPING;
- break;
-
- case 'b':
- if (function != NONE)
- errflg = 1;
- else
- function = BRDCST;
- break;
-
- case 'n':
- portnum = (u_short) atoi(optarg); /* hope we don't get bogus # */
- break;
-
- case '?':
- errflg = 1;
- }
- }
-
- if (errflg || function == NONE) {
- usage();
- return (1);
- }
-
- switch (function) {
-
- case PMAPDUMP:
- if (portnum != 0) {
- usage();
- return (1);
- }
- pmapdump(argc - optind, argv + optind);
- break;
-
- case UDPPING:
- udpping(portnum, argc - optind, argv + optind);
- break;
-
- case TCPPING:
- tcpping(portnum, argc - optind, argv + optind);
- break;
-
- case BRDCST:
- if (portnum != 0) {
- usage();
- return (1);
- }
- brdcst(argc - optind, argv + optind);
- break;
- }
-
- return (0);
- }
-
- static void
- udpping(portnum, argc, argv)
- u_short portnum;
- int argc;
- char **argv;
- {
- struct timeval to;
- struct sockaddr_in addr;
- enum clnt_stat rpc_stat;
- CLIENT *client;
- u_long prognum, vers, minvers, maxvers;
- int sock = RPC_ANYSOCK;
- struct rpc_err rpcerr;
- int failure;
-
- if (argc < 2 || argc > 3) {
- usage();
- exit(1);
- }
- prognum = getprognum(argv[1]);
- get_inet_address(&addr, argv[0]);
- /* Open the socket here so it will survive calls to clnt_destroy */
- sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (sock < 0) {
- perror("rpcinfo: socket");
- exit(1);
- }
- failure = 0;
- if (argc == 2) {
- /*
- * A call to version 0 should fail with a program/version
- * mismatch, and give us the range of versions supported.
- */
- addr.sin_port = htons(portnum);
- to.tv_sec = 5;
- to.tv_usec = 0;
- if ((client = clntudp_create(&addr, prognum, (u_long)0,
- to, &sock)) == NULL) {
- clnt_pcreateerror("rpcinfo");
- printf("program %lu is not available\n",
- prognum);
- exit(1);
- }
- to.tv_sec = 10;
- to.tv_usec = 0;
- rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL,
- xdr_void, (char *)NULL, to);
- if (rpc_stat == RPC_PROGVERSMISMATCH) {
- clnt_geterr(client, &rpcerr);
- minvers = rpcerr.re_vers.low;
- maxvers = rpcerr.re_vers.high;
- } else if (rpc_stat == RPC_SUCCESS) {
- /*
- * Oh dear, it DOES support version 0.
- * Let's try version MAX_VERS.
- */
- addr.sin_port = htons(portnum);
- to.tv_sec = 5;
- to.tv_usec = 0;
- if ((client = clntudp_create(&addr, prognum, MAX_VERS,
- to, &sock)) == NULL) {
- clnt_pcreateerror("rpcinfo");
- printf("program %lu version %lu is not available\n",
- prognum, MAX_VERS);
- exit(1);
- }
- to.tv_sec = 10;
- to.tv_usec = 0;
- rpc_stat = clnt_call(client, NULLPROC, xdr_void,
- (char *)NULL, xdr_void, (char *)NULL, to);
- if (rpc_stat == RPC_PROGVERSMISMATCH) {
- clnt_geterr(client, &rpcerr);
- minvers = rpcerr.re_vers.low;
- maxvers = rpcerr.re_vers.high;
- } else if (rpc_stat == RPC_SUCCESS) {
- /*
- * It also supports version MAX_VERS.
- * Looks like we have a wise guy.
- * OK, we give them information on all
- * 4 billion versions they support...
- */
- minvers = 0;
- maxvers = MAX_VERS;
- } else {
- (void) pstatus(client, prognum, MAX_VERS);
- exit(1);
- }
- } else {
- (void) pstatus(client, prognum, (u_long)0);
- exit(1);
- }
- clnt_destroy(client);
- for (vers = minvers; vers <= maxvers; vers++) {
- addr.sin_port = htons(portnum);
- to.tv_sec = 5;
- to.tv_usec = 0;
- if ((client = clntudp_create(&addr, prognum, vers,
- to, &sock)) == NULL) {
- clnt_pcreateerror("rpcinfo");
- printf("program %lu version %lu is not available\n",
- prognum, vers);
- exit(1);
- }
- to.tv_sec = 10;
- to.tv_usec = 0;
- rpc_stat = clnt_call(client, NULLPROC, xdr_void,
- (char *)NULL, xdr_void, (char *)NULL, to);
- if (pstatus(client, prognum, vers) < 0)
- failure = 1;
- clnt_destroy(client);
- }
- }
- else {
- vers = getvers(argv[2]);
- addr.sin_port = htons(portnum);
- to.tv_sec = 5;
- to.tv_usec = 0;
- if ((client = clntudp_create(&addr, prognum, vers,
- to, &sock)) == NULL) {
- clnt_pcreateerror("rpcinfo");
- printf("program %lu version %lu is not available\n",
- prognum, vers);
- exit(1);
- }
- to.tv_sec = 10;
- to.tv_usec = 0;
- rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
- xdr_void, (char *)NULL, to);
- if (pstatus(client, prognum, vers) < 0)
- failure = 1;
- }
- (void) close(sock); /* Close it up again */
- if (failure)
- exit(1);
- }
-
- static void
- tcpping(portnum, argc, argv)
- u_short portnum;
- int argc;
- char **argv;
- {
- struct timeval to;
- struct sockaddr_in addr;
- enum clnt_stat rpc_stat;
- CLIENT *client;
- u_long prognum, vers, minvers, maxvers;
- int sock = RPC_ANYSOCK;
- struct rpc_err rpcerr;
- int failure;
-
- if (argc < 2 || argc > 3) {
- usage();
- exit(1);
- }
- prognum = getprognum(argv[1]);
- get_inet_address(&addr, argv[0]);
- failure = 0;
- if (argc == 2) {
- /*
- * A call to version 0 should fail with a program/version
- * mismatch, and give us the range of versions supported.
- */
- addr.sin_port = htons(portnum);
- if ((client = clnttcp_create(&addr, prognum, MIN_VERS,
- &sock, 0, 0)) == NULL) {
- clnt_pcreateerror("rpcinfo");
- printf("program %lu is not available\n",
- prognum);
- exit(1);
- }
- to.tv_sec = 10;
- to.tv_usec = 0;
- rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL,
- xdr_void, (char *)NULL, to);
- if (rpc_stat == RPC_PROGVERSMISMATCH) {
- clnt_geterr(client, &rpcerr);
- minvers = rpcerr.re_vers.low;
- maxvers = rpcerr.re_vers.high;
- } else if (rpc_stat == RPC_SUCCESS) {
- /*
- * Oh dear, it DOES support version 0.
- * Let's try version MAX_VERS.
- */
- addr.sin_port = htons(portnum);
- if ((client = clnttcp_create(&addr, prognum, MAX_VERS,
- &sock, 0, 0)) == NULL) {
- clnt_pcreateerror("rpcinfo");
- printf("program %lu version %lu is not available\n",
- prognum, MAX_VERS);
- exit(1);
- }
- to.tv_sec = 10;
- to.tv_usec = 0;
- rpc_stat = clnt_call(client, NULLPROC, xdr_void,
- (char *)NULL, xdr_void, (char *)NULL, to);
- if (rpc_stat == RPC_PROGVERSMISMATCH) {
- clnt_geterr(client, &rpcerr);
- minvers = rpcerr.re_vers.low;
- maxvers = rpcerr.re_vers.high;
- } else if (rpc_stat == RPC_SUCCESS) {
- /*
- * It also supports version MAX_VERS.
- * Looks like we have a wise guy.
- * OK, we give them information on all
- * 4 billion versions they support...
- */
- minvers = 0;
- maxvers = MAX_VERS;
- } else {
- (void) pstatus(client, prognum, MAX_VERS);
- exit(1);
- }
- } else {
- (void) pstatus(client, prognum, MIN_VERS);
- exit(1);
- }
- clnt_destroy(client);
- (void) close(sock);
- sock = RPC_ANYSOCK; /* Re-initialize it for later */
- for (vers = minvers; vers <= maxvers; vers++) {
- addr.sin_port = htons(portnum);
- if ((client = clnttcp_create(&addr, prognum, vers,
- &sock, 0, 0)) == NULL) {
- clnt_pcreateerror("rpcinfo");
- printf("program %lu version %lu is not available\n",
- prognum, vers);
- exit(1);
- }
- to.tv_usec = 0;
- to.tv_sec = 10;
- rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
- xdr_void, (char *)NULL, to);
- if (pstatus(client, prognum, vers) < 0)
- failure = 1;
- clnt_destroy(client);
- (void) close(sock);
- sock = RPC_ANYSOCK;
- }
- }
- else {
- vers = getvers(argv[2]);
- addr.sin_port = htons(portnum);
- if ((client = clnttcp_create(&addr, prognum, vers, &sock,
- 0, 0)) == NULL) {
- clnt_pcreateerror("rpcinfo");
- printf("program %lu version %lu is not available\n",
- prognum, vers);
- exit(1);
- }
- to.tv_usec = 0;
- to.tv_sec = 10;
- rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
- xdr_void, (char *)NULL, to);
- if (pstatus(client, prognum, vers) < 0)
- failure = 1;
- }
- if (failure)
- exit(1);
- }
-
- /*
- * This routine should take a pointer to an "rpc_err" structure, rather than
- * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to
- * a CLIENT structure rather than a pointer to an "rpc_err" structure.
- * As such, we have to keep the CLIENT structure around in order to print
- * a good error message.
- */
- static int
- pstatus(client, prognum, vers)
- register CLIENT *client;
- u_long prognum;
- u_long vers;
- {
- struct rpc_err rpcerr;
-
- clnt_geterr(client, &rpcerr);
- if (rpcerr.re_status != RPC_SUCCESS) {
- clnt_perror(client, "rpcinfo");
- printf("program %lu version %lu is not available\n",
- prognum, vers);
- return (-1);
- } else {
- printf("program %lu version %lu ready and waiting\n",
- prognum, vers);
- return (0);
- }
- }
-
- static void
- pmapdump(argc, argv)
- int argc;
- char **argv;
- {
- struct sockaddr_in server_addr;
- register struct hostent *hp;
- struct pmaplist *head = NULL;
- int socket = RPC_ANYSOCK;
- struct timeval minutetimeout;
- register CLIENT *client;
- struct rpcent *rpc;
-
- if (argc > 1) {
- usage();
- exit(1);
- }
- if (argc == 1)
- get_inet_address(&server_addr, argv[0]);
- else {
- bzero((char *)&server_addr, sizeof server_addr);
- server_addr.sin_family = AF_INET;
- if ((hp = gethostbyname("localhost")) != NULL)
- bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr,
- hp->h_length);
- else
- server_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
- }
- minutetimeout.tv_sec = 60;
- minutetimeout.tv_usec = 0;
- server_addr.sin_port = htons(PMAPPORT);
- if ((client = clnttcp_create(&server_addr, PMAPPROG,
- PMAPVERS, &socket, 50, 500)) == NULL) {
- clnt_pcreateerror("rpcinfo: can't contact portmapper");
- exit(1);
- }
- if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL,
- xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) {
- fprintf(stderr, "rpcinfo: can't contact portmapper: ");
- clnt_perror(client, "rpcinfo");
- exit(1);
- }
- if (head == NULL) {
- printf("No remote programs registered.\n");
- } else {
- printf(" program vers proto port\n");
- for (; head != NULL; head = head->pml_next) {
- printf("%10ld%5ld",
- head->pml_map.pm_prog,
- head->pml_map.pm_vers);
- if (head->pml_map.pm_prot == IPPROTO_UDP)
- printf("%6s", "udp");
- else if (head->pml_map.pm_prot == IPPROTO_TCP)
- printf("%6s", "tcp");
- else
- printf("%6ld", head->pml_map.pm_prot);
- printf("%7ld", head->pml_map.pm_port);
- rpc = getrpcbynumber(head->pml_map.pm_prog);
- if (rpc)
- printf(" %s\n", rpc->r_name);
- else
- printf("\n");
- }
- }
- }
-
- /*
- * reply_proc collects replies from the broadcast.
- * to get a unique list of responses the output of rpcinfo should
- * be piped through sort(1) and then uniq(1).
- */
-
- /*ARGSUSED*/
- static bool_t
- reply_proc(res, who)
- void *res; /* Nothing comes back */
- struct sockaddr_in *who; /* Who sent us the reply */
- {
- register struct hostent *hp;
-
- hp = gethostbyaddr((char *) &who->sin_addr, sizeof who->sin_addr,
- AF_INET);
- printf("%s %s\n", inet_ntoa(who->sin_addr),
- (hp == NULL) ? "(unknown)" : hp->h_name);
- return(FALSE);
- }
-
- static void
- brdcst(argc, argv)
- int argc;
- char **argv;
- {
- enum clnt_stat rpc_stat;
- u_long prognum, vers;
-
- if (argc != 2) {
- usage();
- exit(1);
- }
- prognum = getprognum(argv[0]);
- vers = getvers(argv[1]);
- rpc_stat = clnt_broadcast(prognum, vers, NULLPROC, xdr_void,
- (char *)NULL, xdr_void, (char *)NULL, reply_proc);
- if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) {
- fprintf(stderr, "rpcinfo: broadcast failed: %s\n",
- clnt_sperrno(rpc_stat));
- exit(1);
- }
- exit(0);
- }
-
- static void
- usage()
- {
- fprintf(stderr, "Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n");
- fprintf(stderr, " rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n");
- fprintf(stderr, " rpcinfo -p [ host ]\n");
- fprintf(stderr, " rpcinfo -b prognum versnum\n");
- }
-
- static u_long
- getprognum(arg)
- char *arg;
- {
- register struct rpcent *rpc;
- register u_long prognum;
-
- if (isalpha(*arg)) {
- rpc = getrpcbyname(arg);
- if (rpc == NULL) {
- fprintf(stderr, "rpcinfo: %s is unknown service\n",
- arg);
- exit(1);
- }
- prognum = rpc->r_number;
- } else {
- prognum = (u_long) atoi(arg);
- }
-
- return (prognum);
- }
-
- static u_long
- getvers(arg)
- char *arg;
- {
- register u_long vers;
-
- vers = (int) atoi(arg);
- return (vers);
- }
-
- static void
- get_inet_address(addr, host)
- struct sockaddr_in *addr;
- char *host;
- {
- register struct hostent *hp;
-
- bzero((char *)addr, sizeof *addr);
- addr->sin_addr.s_addr = (u_long) inet_addr(host);
- if (addr->sin_addr.s_addr == -1 || addr->sin_addr.s_addr == 0) {
- if ((hp = gethostbyname(host)) == NULL) {
- fprintf(stderr, "rpcinfo: %s is unknown host\n", host);
- exit(1);
- }
- bcopy(hp->h_addr, (char *)&addr->sin_addr, hp->h_length);
- }
- addr->sin_family = AF_INET;
- }
- Funky_Stuff
- len=`wc -c < rpcinfo.c`
- if [ $len != 15727 ] ; then
- echo error: rpcinfo.c was $len bytes long, should have been 15727
- fi
- cd ..
- echo done with directory etc
- echo x - demo
- echo creating directory demo
- mkdir demo
- cd demo
- echo x - Makefile
- cat > Makefile <<'Funky_Stuff'
- #
- # @(#)Makefile 1.4 87/11/30 3.9 RPCSRC
- #
- #
- # Build all demo services
- #
- MAKE = make
- LIB=-lrpclib
-
- SUBDIR= dir msg sort
-
- all: ${SUBDIR}
-
- clean cleanup:
- cd dir; $(MAKE) ${MFLAGS} cleanup
- cd msg; $(MAKE) ${MFLAGS} cleanup
- cd sort; $(MAKE) ${MFLAGS} cleanup
-
- install:
- @echo "No installations done."
-
- ${SUBDIR}: FRC
- cd $@; $(MAKE) ${MFLAGS} LIB=$(LIB)
-
- FRC:
- Funky_Stuff
- len=`wc -c < Makefile`
- if [ $len != 361 ] ; then
- echo error: Makefile was $len bytes long, should have been 361
- fi
- echo x - dir
- echo creating directory dir
- mkdir dir
- cd dir
- echo x - Makefile
- cat > Makefile <<'Funky_Stuff'
- #
- # @(#)Makefile 1.3 87/11/30 3.9 RPCSRC
- #
- BIN = dir_svc rls
- GEN = dir_clnt.c dir_svc.c dir_xdr.c dir.h
- LIB = -lrpclib
- RPCCOM = rpcgen
-
- all: $(BIN)
-
- $(GEN): dir.x
- $(RPCCOM) dir.x
-
- dir_svc: dir_proc.o dir_svc.o dir_xdr.o
- $(CC) -o $@ dir_proc.o dir_svc.o dir_xdr.o $(LIB)
-
- rls: rls.o dir_clnt.o dir_xdr.o
- $(CC) -o $@ rls.o dir_clnt.o dir_xdr.o $(LIB)
-
- rls.o: rls.c dir.h
-
- dir_proc.o: dir_proc.c dir.h
-
- clean cleanup:
- rm -f $(GEN) *.o $(BIN)
-
- Funky_Stuff
- len=`wc -c < Makefile`
- if [ $len != 444 ] ; then
- echo error: Makefile was $len bytes long, should have been 444
- fi
- echo x - dir.x
- cat > dir.x <<'Funky_Stuff'
- /* @(#)dir.x 1.1 87/11/04 3.9 RPCSRC */
- /*
- * dir.x: Remote directory listing protocol
- */
- const MAXNAMELEN = 255; /* maximum length of a directory entry */
-
- typedef string nametype<MAXNAMELEN>; /* a directory entry */
-
- typedef struct namenode *namelist; /* a link in the listing */
-
- /*
- * A node in the directory listing
- */
- struct namenode {
- nametype name; /* name of directory entry */
- namelist next; /* next entry */
- };
-
- /*
- * The result of a READDIR operation.
- */
- union readdir_res switch (int errno) {
- case 0:
- namelist list; /* no error: return directory listing */
- default:
- void; /* error occurred: nothing else to return */
- };
-
- /*
- * The directory program definition
- */
- program DIRPROG {
- version DIRVERS {
- readdir_res
- READDIR(nametype) = 1;
- } = 1;
- } = 76;
- Funky_Stuff
- len=`wc -c < dir.x`
- if [ $len != 780 ] ; then
- echo error: dir.x was $len bytes long, should have been 780
- fi
- echo x - dir_proc.c
- cat > dir_proc.c <<'Funky_Stuff'
- /* @(#)dir_proc.c 1.3 87/11/16 3.9 RPCSRC */
- /*
- * dir_proc.c: remote readdir implementation
- */
- #include <rpc/rpc.h>
- #include <sys/dir.h>
- #include "dir.h"
-
- extern int errno;
- extern char *malloc();
- extern char *strcpy();
-
- readdir_res *
- readdir_1(dirname)
- nametype *dirname;
- {
- DIR *dirp;
- struct direct *d;
- namelist nl;
- namelist *nlp;
- static readdir_res res; /* must be static! */
-
- /*
- * Open directory
- */
- dirp = opendir(*dirname);
- if (dirp == NULL) {
- res.errno = errno;
- return (&res);
- }
-
- /*
- * Free previous result
- */
- xdr_free(xdr_readdir_res, &res);
-
- /*
- * Collect directory entries
- */
- nlp = &res.readdir_res_u.list;
- while (d = readdir(dirp)) {
- nl = *nlp = (namenode *) malloc(sizeof(namenode));
- nl->name = malloc(strlen(d->d_name)+1);
- strcpy(nl->name, d->d_name);
- nlp = &nl->next;
- }
- *nlp = NULL;
-
- /*
- * Return the result
- */
- res.errno = 0;
- closedir(dirp);
- return (&res);
- }
- Funky_Stuff
- len=`wc -c < dir_proc.c`
- if [ $len != 919 ] ; then
- echo error: dir_proc.c was $len bytes long, should have been 919
- fi
- echo x - rls.c
- cat > rls.c <<'Funky_Stuff'
- /* @(#)rls.c 1.1 87/11/04 3.9 RPCSRC */
- /*
- * rls.c: Remote directory listing client
- */
- #include <stdio.h>
- #include <rpc/rpc.h> /* always need this */
- #include "dir.h" /* need this too: will be generated by rpcgen*/
-
- extern int errno;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- CLIENT *cl;
- char *server;
- char *dir;
- readdir_res *result;
- namelist nl;
-
-
- if (argc != 3) {
- fprintf(stderr, "usage: %s host directory\n", argv[0]);
- exit(1);
- }
-
- /*
- * Remember what our command line arguments refer to
- */
- server = argv[1];
- dir = argv[2];
-
- /*
- * Create client "handle" used for calling MESSAGEPROG on the
- * server designated on the command line. We tell the rpc package
- * to use the "tcp" protocol when contacting the server.
- */
- cl = clnt_create(server, DIRPROG, DIRVERS, "tcp");
- if (cl == NULL) {
- /*
- * Couldn't establish connection with server.
- * Print error message and die.
- */
- clnt_pcreateerror(server);
- exit(1);
- }
-
- /*
- * Call the remote procedure "readdir" on the server
- */
- result = readdir_1(&dir, cl);
- if (result == NULL) {
- /*
- * An error occurred while calling the server.
- * Print error message and die.
- */
- clnt_perror(cl, server);
- exit(1);
- }
-
- /*
- * Okay, we successfully called the remote procedure.
- */
- if (result->errno != 0) {
- /*
- * A remote system error occurred.
- * Print error message and die.
- */
- errno = result->errno;
- perror(dir);
- exit(1);
- }
-
- /*
- * Successfuly got a directory listing.
- * Print it out.
- */
- for (nl = result->readdir_res_u.list; nl != NULL; nl = nl->next) {
- printf("%s\n", nl->name);
- }
- }
- Funky_Stuff
- len=`wc -c < rls.c`
- if [ $len != 1611 ] ; then
- echo error: rls.c was $len bytes long, should have been 1611
- fi
- cd ..
- echo done with directory dir
- echo x - msg
- echo creating directory msg
- mkdir msg
- cd msg
- echo x - Makefile
- cat > Makefile <<'Funky_Stuff'
- #
- # @(#)Makefile 1.4 87/11/30 3.9 RPCSRC
- #
- BIN = printmsg msg_svc rprintmsg
- GEN = msg_clnt.c msg_svc.c msg.h
- LIB = -lrpclib
- RPCCOM = rpcgen
-
- all: $(BIN)
-
- #
- # This is the non-networked version of the program
- #
- printmsg: printmsg.o
- $(CC) -o $@ printmsg.o
-
- #
- # note: no xdr routines are generated here, due this service's
- # use of basic data types.
- #
- $(GEN): msg.x
- $(RPCCOM) msg.x
-
- msg_svc: msg_proc.o msg_svc.o
- $(CC) -o $@ msg_proc.o msg_svc.o $(LIB)
-
- rprintmsg: rprintmsg.o msg_clnt.o
- $(CC) -o $@ rprintmsg.o msg_clnt.o $(LIB)
-
- rprintmsg.o: rprintmsg.c msg.h
-
- msg_proc.o: msg_proc.c msg.h
-
- clean cleanup:
- rm -f $(GEN) *.o $(BIN)
-
- Funky_Stuff
- len=`wc -c < Makefile`
- if [ $len != 640 ] ; then
- echo error: Makefile was $len bytes long, should have been 640
- fi
- echo x - msg.x
- cat > msg.x <<'Funky_Stuff'
- /* @(#)msg.x 1.1 87/11/04 3.9 RPCSRC */
- /*
- * msg.x: Remote message printing protocol
- */
- program MESSAGEPROG {
- version MESSAGEVERS {
- int PRINTMESSAGE(string) = 1;
- } = 1;
- } = 99;
- Funky_Stuff
- len=`wc -c < msg.x`
- if [ $len != 183 ] ; then
- echo error: msg.x was $len bytes long, should have been 183
- fi
- echo x - msg_proc.c
- cat > msg_proc.c <<'Funky_Stuff'
- /* @(#)msg_proc.c 1.1 87/11/04 3.9 RPCSRC */
- /*
- * msg_proc.c: implementation of the remote procedure "printmessage"
- */
- #include <stdio.h>
- #include <rpc/rpc.h> /* always need this here */
- #include "msg.h" /* need this too: msg.h will be generated by rpcgen */
-
- /*
- * Remote verson of "printmessage"
- */
- int *
- printmessage_1(msg)
- char **msg;
- {
- static int result; /* must be static! */
- FILE *f;
-
- f = fopen("/dev/console", "w");
- if (f == NULL) {
- result = 0;
- return (&result);
- }
- fprintf(f, "%s\n", *msg);
- fclose(f);
- result = 1;
- return (&result);
- }
- Funky_Stuff
- len=`wc -c < msg_proc.c`
- if [ $len != 562 ] ; then
- echo error: msg_proc.c was $len bytes long, should have been 562
- fi
- echo x - printmsg.c
- cat > printmsg.c <<'Funky_Stuff'
- /* @(#)printmsg.c 1.1 87/11/04 3.9 RPCSRC */
- /*
- * printmsg.c: print a message on the console
- */
- #include <stdio.h>
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *message;
-
- if (argc < 2) {
- fprintf(stderr, "usage: %s <message>\n", argv[0]);
- exit(1);
- }
- message = argv[1];
-
- if (!printmessage(message)) {
- fprintf(stderr, "%s: sorry, couldn't print your message\n",
- argv[0]);
- exit(1);
- }
- printf("Message delivered!\n");
- }
-
- /*
- * Print a message to the console.
- * Return a boolean indicating whether the message was actually printed.
- */
- printmessage(msg)
- char *msg;
- {
- FILE *f;
-
- f = fopen("/dev/console", "w");
- if (f == NULL) {
- return (0);
- }
- fprintf(f, "%s\n", msg);
- fclose(f);
- return(1);
- }
- Funky_Stuff
- len=`wc -c < printmsg.c`
- if [ $len != 720 ] ; then
- echo error: printmsg.c was $len bytes long, should have been 720
- fi
- echo x - rprintmsg.c
- cat > rprintmsg.c <<'Funky_Stuff'
- /* @(#)rprintmsg.c 1.1 87/11/04 3.9 RPCSRC */
- /*
- * rprintmsg.c: remote version of "printmsg.c"
- */
- #include <stdio.h>
- #include <rpc/rpc.h> /* always need this */
- #include "msg.h" /* need this too: will be generated by rpcgen*/
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- CLIENT *cl;
- int *result;
- char *server;
- char *message;
-
- if (argc < 3) {
- fprintf(stderr, "usage: %s host message\n", argv[0]);
- exit(1);
- }
-
- /*
- * Remember what our command line arguments refer to
- */
- server = argv[1];
- message = argv[2];
-
- /*
- * Create client "handle" used for calling MESSAGEPROG on the
- * server designated on the command line. We tell the rpc package
- * to use the "tcp" protocol when contacting the server.
- */
- cl = clnt_create(server, MESSAGEPROG, MESSAGEVERS, "tcp");
- if (cl == NULL) {
- /*
- * Couldn't establish connection with server.
- * Print error message and die.
- */
- clnt_pcreateerror(server);
- exit(1);
- }
-
- /*
- * Call the remote procedure "printmessage" on the server
- */
- result = printmessage_1(&message, cl);
- if (result == NULL) {
- /*
- * An error occurred while calling the server.
- * Print error message and die.
- */
- clnt_perror(cl, server);
- exit(1);
- }
-
- /*
- * Okay, we successfully called the remote procedure.
- */
- if (*result == 0) {
- /*
- * Server was unable to print our message.
- * Print error message and die.
- */
- fprintf(stderr, "%s: sorry, %s couldn't print your message\n",
- argv[0], server);
- exit(1);
- }
-
- /*
- * The message got printed on the server's console
- */
- printf("Message delivered to %s!\n", server);
- }
- Funky_Stuff
- len=`wc -c < rprintmsg.c`
- if [ $len != 1599 ] ; then
- echo error: rprintmsg.c was $len bytes long, should have been 1599
- fi
- cd ..
- echo done with directory msg
- echo x - sort
- echo creating directory sort
- mkdir sort
- cd sort
- echo x - Makefile
- cat > Makefile <<'Funky_Stuff'
- #
- # @(#)Makefile 1.4 87/11/30 3.9 RPCSRC
- #
-
- BIN = rsort sort_svc
- GEN = sort_clnt.c sort_svc.c sort_xdr.c sort.h
- LIB = -lrpclib
- RPCCOM = rpcgen
-
- all: $(BIN)
-
- rsort: rsort.o sort_clnt.o sort_xdr.o
- $(CC) $(LDFLAGS) -o $@ rsort.o sort_clnt.o sort_xdr.o $(LIB)
-
- rsort.o: rsort.c sort.h
-
- sort_clnt.c:
- $(RPCCOM) -l sort.x >$@
-
- sort_svc: sort_proc.o sort_svc.o sort_xdr.o
- $(CC) $(LDFLAGS) -o $@ sort_proc.o sort_svc.o sort_xdr.o $(LIB)
-
- sort_proc.o: sort_proc.c sort.h
-
- sort_svc.c:
- $(RPCCOM) -s udp sort.x >$@
-
- sort_xdr.c:
- $(RPCCOM) -c sort.x >$@
-
- sort.h:
- $(RPCCOM) -h sort.x >$@
-
- clean cleanup:
- rm -f $(GEN) *.o $(BIN)
-
- Funky_Stuff
- len=`wc -c < Makefile`
- if [ $len != 621 ] ; then
- echo error: Makefile was $len bytes long, should have been 621
- fi
- echo x - rsort.c
- cat > rsort.c <<'Funky_Stuff'
- /* @(#)rsort.c 1.2 87/11/24 3.9 RPCSRC */
- /*
- * rsort.c
- * Client side application which sorts argc, argv.
- */
- #include <stdio.h>
- #include <rpc/rpc.h>
- #include "sort.h"
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- char *machinename;
- struct sortstrings args, res;
- int i;
-
- if (argc < 3) {
- fprintf(stderr, "usage: %s machinename [s1 ...]\n", argv[0]);
- exit(1);
- }
- machinename = argv[1];
- args.ss.ss_len = argc - 2; /* substract off progname, machinename */
- args.ss.ss_val = &argv[2];
- res.ss.ss_val = (char **)NULL;
-
- if ((i = callrpc(machinename, SORTPROG, SORTVERS, SORT,
- xdr_sortstrings, &args, xdr_sortstrings, &res)))
- {
- fprintf(stderr, "%s: call to sort service failed. ", argv[0]);
- clnt_perrno(i);
- fprintf(stderr, "\n");
- exit(1);
- }
-
- for (i = 0; i < res.ss.ss_len; i++) {
- printf("%s\n", res.ss.ss_val[i]);
- }
-
- /* should free res here */
- exit(0);
- }
-
- Funky_Stuff
- len=`wc -c < rsort.c`
- if [ $len != 897 ] ; then
- echo error: rsort.c was $len bytes long, should have been 897
- fi
- echo x - sort.x
- cat > sort.x <<'Funky_Stuff'
- /* @(#)sort.x 1.1 87/11/04 3.9 RPCSRC */
- /*
- * The sort procedure receives an array of strings and returns an array
- * of strings. This toy service handles a maximum of 64 strings.
- */
- const MAXSORTSIZE = 64;
- const MAXSTRINGLEN = 64;
-
- typedef string str<MAXSTRINGLEN>; /* the string itself */
-
- struct sortstrings {
- str ss<MAXSORTSIZE>;
- };
-
- program SORTPROG {
- version SORTVERS {
- sortstrings SORT(sortstrings) = 1;
- } = 1;
- } = 22855;
- Funky_Stuff
- len=`wc -c < sort.x`
- if [ $len != 455 ] ; then
- echo error: sort.x was $len bytes long, should have been 455
- fi
- echo x - sort_proc.c
- cat > sort_proc.c <<'Funky_Stuff'
- /* @(#)sort_proc.c 1.2 87/11/24 3.9 RPCSRC */
- #include <rpc/rpc.h>
- #include "sort.h"
-
- static int
- comparestrings(sp1, sp2)
- char **sp1, **sp2;
- {
- return (strcmp(*sp1, *sp2));
- }
-
- struct sortstrings *
- sort_1(ssp)
- struct sortstrings *ssp;
- {
- static struct sortstrings ss_res;
-
- if (ss_res.ss.ss_val != (str *)NULL)
- free(ss_res.ss.ss_val);
-
- qsort(ssp->ss.ss_val, ssp->ss.ss_len, sizeof (char *), comparestrings);
- ss_res.ss.ss_len = ssp->ss.ss_len;
- ss_res.ss.ss_val = (str *)malloc(ssp->ss.ss_len * sizeof(str *));
- bcopy(ssp->ss.ss_val, ss_res.ss.ss_val,
- ssp->ss.ss_len * sizeof(str *));
- return(&ss_res);
- }
- Funky_Stuff
- len=`wc -c < sort_proc.c`
- if [ $len != 653 ] ; then
- echo error: sort_proc.c was $len bytes long, should have been 653
- fi
- cd ..
- echo done with directory sort
- cd ..
- echo done with directory demo
- exit
-